import os
import sys
import json
import shutil
import unittest
import filecmp

# _BASE_DIR is the root directory of the tool and needs to be added to sys.path.
_BASE_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(_BASE_DIR)

from framework.config_parser import ConfigFileParser
from framework.options_combiner import OptionCombiner
from framework.report.pre_report import PreReport
from framework.report.csv_report import CSVReport


class CSVReportTestCase(unittest.TestCase):
    CUR_DIR = os.path.dirname(os.path.abspath(__file__))
    TEST_DATA_DIR = "test_data"
    CSV_FILE = "gcbs.csv"

    @classmethod
    def setUpClass(cls):
        cls.result_dir = os.path.join(cls.CUR_DIR, "csv_report_data")
        cls.output_dir = os.path.join(cls.CUR_DIR, "output_dir")
        cls.test_data_dir = os.path.join(cls.CUR_DIR, cls.TEST_DATA_DIR)
        cls.csv_dir = os.path.join(cls.result_dir, cls.CSV_FILE)
        config_file = os.path.join(cls.CUR_DIR, "../config", "config_sample.ini")
        config_opts = ConfigFileParser().parse_ini(config_file)
        cls.option = OptionCombiner().combine_options(config_opts, {})

    def setUp(self):
        if os.path.exists(self.result_dir):
            shutil.rmtree(self.result_dir)
        os.makedirs(self.result_dir)
        if os.path.exists(self.output_dir):
            shutil.rmtree(self.output_dir)
        os.makedirs(self.output_dir)

    def tearDown(self):
        """
        Delete the data directory generated by test cases.
        """
        if os.path.exists(self.result_dir):
            shutil.rmtree(self.result_dir)
        if os.path.exists(self.output_dir):
            shutil.rmtree(self.output_dir)

    def test_make_report_001(self):
        with open(os.path.join(self.TEST_DATA_DIR, "test_normal.json"), "rb") as file:
            json_data = json.load(file)
        pre_report = PreReport(json_data, self.option)
        test_data = pre_report.get_report_data()
        csv_report = CSVReport(self.csv_dir, test_data)
        csv_report.make_report()
        self.assertTrue(filecmp.cmp(os.path.join(self.TEST_DATA_DIR, "normal.csv"), self.csv_dir))

    def test_make_report_002(self):
        with open(os.path.join(self.TEST_DATA_DIR, "test_single_suite.json"), "rb") as file:
            json_data = json.load(file)
        pre_report = PreReport(json_data, self.option)
        test_data = pre_report.get_report_data()
        csv_report = CSVReport(self.csv_dir, test_data)
        csv_report.make_report()
        self.assertTrue(filecmp.cmp(os.path.join(self.TEST_DATA_DIR, "single_suite.csv"), self.csv_dir))

    def test_make_report_003(self):
        with open(os.path.join(self.TEST_DATA_DIR, "test_no_workloads.json"), "rb") as file:
            json_data = json.load(file)
        pre_report = PreReport(json_data, self.option)
        test_data = pre_report.get_report_data()
        csv_report = CSVReport(self.csv_dir, test_data)
        csv_report.make_report()
        self.assertTrue(filecmp.cmp(os.path.join(self.TEST_DATA_DIR, "no_workloads.csv"), self.csv_dir))

    def test_make_report_004(self):
        with open(os.path.join(self.TEST_DATA_DIR, "test_multi_suites.json"), "rb") as file:
            json_data = json.load(file)
        pre_report = PreReport(json_data, self.option)
        test_data = pre_report.get_report_data()
        csv_report = CSVReport(self.csv_dir, test_data)
        csv_report.make_report()
        self.assertTrue(filecmp.cmp(os.path.join(self.TEST_DATA_DIR, "multi_suites.csv"), self.csv_dir))


if __name__ == "__main__":
    suite = unittest.TestLoader().loadTestsFromTestCase(CSVReportTestCase)
    unittest.TextTestRunner(verbosity=2).run(suite)
